package com.siecom.tool;



import android.content.Context;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.Toast;

import java.io.BufferedInputStream;

import java.io.BufferedOutputStream;

import java.io.File;

import java.io.FileInputStream;

import java.io.FileNotFoundException;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.InputStream;

import java.io.OutputStream;

import java.io.UnsupportedEncodingException;

import java.nio.charset.StandardCharsets;
import java.util.ArrayList;

import java.util.Collection;

import java.util.Enumeration;

import java.util.zip.CRC32;
import java.util.zip.CheckedOutputStream;
import java.util.zip.ZipEntry;

import java.util.zip.ZipException;

import java.util.zip.ZipFile;

import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;


public class ZipUtil {

    private static final String TAG = ZipUtil.class.getSimpleName();

    /**
     * 在/data/data/下创建一个res文件夹，存放4个文件
     */
    private void copyDbFile(Context context, String fileName) {
        InputStream in = null;
        FileOutputStream out = null;
        String path = "/data/data/" + context.getPackageName() + "/file/res/";
        File file = new File(path + fileName);

        //创建文件夹
        File filePath = new File(path);
        if (!filePath.exists())
            filePath.mkdirs();

        if (file.exists())
            return;

        try {
            in = context.getAssets().open(fileName); // 从assets目录下复制
            out = new FileOutputStream(file);
            int length = -1;
            byte[] buf = new byte[1024];
            while ((length = in.read(buf)) != -1) {
                out.write(buf, 0, length);
            }
            out.flush();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (in != null) in.close();
                if (out != null) out.close();
            } catch (IOException e1) {
                e1.printStackTrace();
            }
        }
    }

    /**
     *
     * @param path 要解压到哪个文件夹 //压缩到此处
     */
    public static void compressFile(String path) {

        //要压缩的文件的路径
        File file = new File(path + "sign.zip");
        if (file.exists()){
            file.delete();
        }
        //创建文件夹
        File filePath = new File(path);
        if (!filePath.exists())
            filePath.mkdirs();

        if (file.exists())
            return;

        try {
            ZipOutputStream zipOutputStream = new ZipOutputStream(new CheckedOutputStream(new FileOutputStream(file),new CRC32()));
            zip(zipOutputStream,"signature.txt",new File(path+"signature.txt"));
            zipOutputStream.flush();
            zipOutputStream.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     *
     * @param zipOutputStream
     * @param name 文件名
     * @param fileSrc 目录
     * @throws IOException
     */

    private static void zip(ZipOutputStream zipOutputStream,String name, File fileSrc) throws IOException {

        if (fileSrc.isDirectory()) {
            System.out.println("需要压缩的地址是目录");
            File[] files = fileSrc.listFiles();

            name = name+"/";
            zipOutputStream.putNextEntry(new ZipEntry(name));  // 建一个文件夹
            System.out.println("目录名: "+name);

            for (File f : files) {
                zip(zipOutputStream,name+f.getName(),f);
                System.out.println("目录: "+name+f.getName());
            }

        }else {
            System.out.println("需要压缩的地址是文件");
            zipOutputStream.putNextEntry(new ZipEntry(name));
            System.out.println("文件名: "+name);
            FileInputStream input = new FileInputStream(fileSrc);
            System.out.println("文件路径: "+fileSrc);
            byte[] buf = new byte[1024];
            int len = -1;

            while ((len = input.read(buf)) != -1) {
                zipOutputStream.write(buf, 0, len);
            }

            zipOutputStream.flush();
            input.close();
        }
    }


    /**
     * 解压缩
     * @param fileName 要解压的 zip文件名称
     * @param path 要生成的文件名称全路径
     */
    public static void unZip(String fileName,String path) {

        File FILE = new File(fileName);
        LogUtil.e(TAG,"length == " + FILE.length());
        try {
            upZipFile(FILE, path);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    /**
     * 解压缩
     * 将zipFile文件解压到folderPath目录下.
     * @param zipFile zip文件
     * @param folderPath 解压到的地址
     * @throws IOException
     */
    private static void upZipFile(File zipFile, String folderPath) throws IOException {
        ZipFile zfile = new ZipFile(zipFile);
        Enumeration zList = zfile.entries();
        ZipEntry ze = null;
        byte[] buf = new byte[1024];
        while (zList.hasMoreElements()) {
            ze = (ZipEntry) zList.nextElement();
            if (ze.isDirectory()) {
                Log.d(TAG, "ze.getName() = " + ze.getName());
                String dirstr = folderPath + ze.getName();
                dirstr = new String(dirstr.getBytes("8859_1"), StandardCharsets.UTF_8);
                Log.d(TAG, "str = " + dirstr);
                File f = new File(dirstr);
                f.mkdir();
                continue;
            }
            Log.d(TAG, "ze.getName() = " + ze.getName());
            OutputStream os = new BufferedOutputStream(new FileOutputStream(getRealFileName(folderPath, ze.getName())));
            InputStream is = new BufferedInputStream(zfile.getInputStream(ze));
            int readLen = 0;
            while ((readLen = is.read(buf, 0, 1024)) != -1) {
                os.write(buf, 0, readLen);
            }
            is.close();
            os.close();
        }
        zfile.close();
    }

    /**
     * 给定根目录，返回一个相对路径所对应的实际文件名.
     * @param baseDir     指定根目录
     * @param absFileName 相对路径名，来自于ZipEntry中的name
     * @return java.io.File 实际的文件
     */
    public static File getRealFileName(String baseDir, String absFileName) {
        String[] dirs = absFileName.split("/");
        File ret = new File(baseDir);
        String substr = null;
        if (dirs.length > 1) {
            for (int i = 0; i < dirs.length - 1; i++) {
                substr = dirs[i];
                try {
                    substr = new String(substr.getBytes("8859_1"), "GB2312");
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                }
                ret = new File(ret, substr);

            }
            Log.d(TAG, "1ret = " + ret);
            if (!ret.exists())
                ret.mkdirs();
            substr = dirs[dirs.length - 1];
            try {
                substr = new String(substr.getBytes("8859_1"), "GB2312");
                Log.d(TAG, "substr = " + substr);
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
            ret = new File(ret, substr);
            Log.d(TAG, "2ret = " + ret);
            return ret;
        }
        return ret;
    }


//    public static void ZipFolder(String srcFileString, String zipFileString) {
//        //创建ZIP
//        try {
//            File fileZip = new File(zipFileString + ".zip");
//
//            ZipOutputStream outZip = new ZipOutputStream(new FileOutputStream(fileZip));
//            //创建文件
//            File file = new File(srcFileString);
//            //压缩
//            ZipFiles(file.getParent() + File.separator, file.getName(), outZip);
//            //完成和关闭
//            outZip.finish();
//            outZip.close();
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
//    }
//    public static void ZipFiles(String folderString, String fileString, ZipOutputStream zipOutputSteam) {
//        try {
//            if (zipOutputSteam == null)
//                return;
//            File file = new File(folderString + fileString);
//            if (file.isFile()) {
//                ZipEntry zipEntry = new ZipEntry(fileString);
//                FileInputStream inputStream = new FileInputStream(file);
//                zipOutputSteam.putNextEntry(zipEntry);
//                int len;
//                byte[] buffer = new byte[4096];
//                while ((len = inputStream.read(buffer)) != -1) {
//                    zipOutputSteam.write(buffer, 0, len);
//                }
//                zipOutputSteam.closeEntry();
//            } else {
//                //文件夹
//                String fileList[] = file.list();
//                //没有子文件和压缩
//                if (fileList.length <= 0) {
//                    ZipEntry zipEntry = new ZipEntry(fileString + File.separator);
//                    zipOutputSteam.putNextEntry(zipEntry);
//                    zipOutputSteam.closeEntry();
//                }
//                //子文件和递归
//                for (int i = 0; i < fileList.length; i++) {
//                    ZipFiles(folderString + fileString + "/", fileList[i], zipOutputSteam);
//                }
//            }
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
//    }

    //过滤在mac上压缩时自动生成的__MACOSX文件夹

    private static final String MAC_IGNORE = "__MACOSX/";

    /**
     *
     * @param target 要生成的文件
     * @param source 源文件 zip文件
     */
    public static void decompressFile(String target, String source) {

        if(TextUtils.isEmpty(target)){

            return;

        }

        try {

            File file = new File(source);
            LogUtil.e(TAG,"file length == " + file.length());
            if(!file.exists()) {

                return;

            }

            ZipFile zipFile = new ZipFile(file);

            ZipInputStream zipInputStream = new ZipInputStream(new FileInputStream(file));

            ZipEntry zipEntry = null;

            while ((zipEntry = zipInputStream.getNextEntry()) != null) {

                String fileName = zipEntry.getName();

                if(fileName != null && fileName.contains(MAC_IGNORE)) {

                    continue;

                }

                File temp = new File(target + File.separator + fileName);

                if(zipEntry.isDirectory()) {

                    File dir = new File(target + File.separator + fileName);

                    dir.mkdirs();

                    continue;

                }

                if (temp.getParentFile() != null && !temp.getParentFile().exists()) {

                    temp.getParentFile().mkdirs();

                }

                byte[] buffer = new byte[1024];

                OutputStream os = new FileOutputStream(temp);

// 通过ZipFile的getInputStream方法拿到具体的ZipEntry的输入流

                InputStream is = zipFile.getInputStream(zipEntry);

                int len = 0;

                while ((len = is.read(buffer)) != -1) {

                    os.write(buffer, 0, len);

                }

                os.close();

                is.close();

            }

            zipInputStream.close();

        } catch (Exception e) {

            e.printStackTrace();

        }
    }

}
